home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-18 | 26.7 KB | 1,148 lines |
- ;========================================================================
- ;60Hz emulator (PAL-NTSC) V1.05 by P. de Boer in 1991
- ;
- ;The program was inspired by Power Utility from Amicon and
- ;BootPAL/BootNTSC by Nico Francois.
- ;
- ;PS: my monitor (1084s) synchronizes from 47.5Hz to 65Hz
- ; when VBI frequency is 55Hz then the monitor switches.
- ;
- ;========================================================================
- ;Options:
- ;Press : <LEFT-ALT>+<LEFT-SHIFT>+<CTRL> and :
- ;
- ; 1 - Toggle color bar
- ; 2 - Default values
- ; 3 - Add ± one line to timer buffer
- ; 4 - Sub ± one line to timer buffer
- ; 5 - Add one line to total of rasterlines (decreases VBI frequenzy)
- ; 6 - Sub one line from total of rasterlines (increases VBI frequenzy)
- ; 7 - Add one line to end of display
- ; 8 - Sub one line from end of display
-
- ; ESC - To kill the emulator
- ; 9 - Toggle between Software and Hardware emulation
- ; 0 - Toggle between 50Hz and 60Hz
- ;
- ;========================================================================
- ;Now some stuff we need !
- ;========================================================================
-
- RSRESET ;little structure for my flags
- Flag_60Hz RS.B 1
- Flag_Color RS.B 1
- Flag_OverScan RS.B 1
- Flag_Enable RS.B 1
- Flag_FatAgnus RS.B 1
- Flag_Resident RS.B 1
-
- NULL EQU 0
-
- is_data EQU 14 ;some stuff from the system's include
- is_code EQU 18 ;files
-
- gb_DisplayFlags EQU 206 ;graphics
- gb_DisplayRows EQU 212
- gb_NormalDisplayRows EQU 216
- VBlankFrequency EQU 530
-
- _LVODisplayAlert EQU -90 ;intuition
-
- _LVOOpen EQU -30 ;dos
- _LVOClose EQU -36
- _LVORead EQU -42
- _LVOWrite EQU -48
- _LVOInput EQU -54
- _LVOOutput EQU -60
-
- MODE_OLD EQU 1005 ;dos
- MODE_NEW EQU 1006
- PR_CLI EQU $AC
- PR_MSGPORT EQU $5C
-
- _LVOAlert EQU -108 ;exec
- _LVODisable EQU -120
- _LVOEnable EQU -126
- _LVOForbid EQU -132
- _LVOPermit EQU -138
- _LVOAddIntServer EQU -168
- _LVORemIntServer EQU -174
- _LVOAllocMem EQU -198
- _LVOFreeMem EQU -210
- _LVOAddPort EQU -354
- _LVORemPort EQU -360
- _LVOPutMsg EQU -366
- _LVOGetMsg EQU -372
- _LVOFindPort EQU -390
- _LVOCloseLibrary EQU -414
- _LVOSumLibrary EQU -426
- _LVOOpenResource EQU -498
- _LVOOpenLibrary EQU -552
- _LVOSumKickData EQU -612
- _LVOCopyMem EQU -624
-
- ExecBase EQU $4
-
- LIBF_CHANGED EQU 2
- LIB_FLAGS EQU 14
-
- RSRESET ;node structure
- LN RS.B 0
- LN_SUCC RS.L 1
- LN_PRED RS.L 1
- LN_TYPE RS.B 1
- LN_PRI RS.B 1
- LN_NAME RS.L 1
- LN_SIZE RS.W 0
-
- NT_MSGPORT EQU 4
- NT_MESSAGE EQU 5
-
- RSRESET ;memlist structure
- ML RS.B LN_SIZE
- ML_NUMENTRIES RS.W 1
- ML_ME RS.W 0
- ML_SIZE RS.W 0
-
- RSRESET
- ME RS.B 0
- ME_REQS RS.W 0
- ME_ADDR RS.L 1
- ME_LENGTH RS.L 1
- ME_SIZE RS.W 0
-
- MEMF_PUBLIC EQU 1<<0
- MEMF_CHIP EQU 1<<1
-
- RSRESET ;resident structure
- RT RS.B 0
- RT_MATCHWORD RS.W 1
- RT_MATCHTAG RS.L 1
- RT_ENDSKIP RS.L 1
- RT_FLAGS RS.B 1
- RT_VERSION RS.B 1
- RT_TYPE RS.B 1
- RT_PRI RS.B 1
- RT_NAME RS.L 1
- RT_IDSTRING RS.L 1
- RT_INIT RS.L 1
- RT_SIZE RS.W 0
-
- RTC_MATCHWORD EQU $4AFC
- RTB_COLDSTART EQU 0
- RTF_COLDSTART EQU 1<<0
- RTB_AUTOINIT EQU 7
- RTF_AUTOINIT EQU 1<<7
- RTM_WHEN EQU 1
- RTW_NEVER EQU 0
- RTW_COLDSTART EQU 1
-
- KickMemPtr EQU 546 ;execbase equ's
- KickTagPtr EQU 550
- KickCheckSum EQU 554
-
- DMACONR EQU $002 ;custom chip addresses
- VPOSR EQU $004
- VHPOSR EQU $006
- VPOSW EQU $02A
- VHPOSW EQU $02C
- DIWSTRT EQU $08E
- DIWSTOP EQU $090
- DMACON EQU $096
- COLOR00 EQU $180
- BEAMCON0 EQU $1DC
- CUSTOM EQU $DFF000
-
- CIAB EQU $BFD000
- CIAA EQU $BFE001
-
- PRA EQU $000
- PRB EQU $100
- DDRA EQU $200
- DDRB EQU $300
- TALO EQU $400
- TAHI EQU $500
- TBLO EQU $600
- TBHI EQU $700
- SPx EQU $C00
- ICR EQU $D00
- CRA EQU $E00
- CRB EQU $F00
-
- ;========================================================================
- CALL MACRO
- IFC 'EXEC','\1'
- MOVEA.L (ExecBase).W,A6
- ENDC
- IFNC 'EXEC','\1'
- MOVEA.L \1Base,A6
- ENDC
- JSR _LVO\2(A6)
- ENDM
-
- OPENLIB MACRO
- LEA \1Name(PC),A1
- CLR.L D0
- CALL EXEC,OpenLibrary
- MOVE.L D0,\1Base
- BEQ \2
- ENDM
-
- CLOSELIB MACRO
- MOVEA.L \1Base,A1
- CALL EXEC,CloseLibrary
- ENDM
-
- ;========================================================================
- ;Here we go !!!
- ;========================================================================
- opt o+
-
- InstallEmulator move.l a0,a5 ;store pointer to cmd line
- st Flag_Resident+Flags
-
- ;===============================================
- CheckForAgnus move.w $DFF004,d0 ;check what kind of agnus
- and.w #$2000,d0 ;we got
- beq.s .OldAgnus
- st Flag_FatAgnus+Flags
- .OldAgnus
- ;===============================================
- OpenDosLib OPENLIB DOS,NoDOS ;open dos library
- CALL DOS,Output ;get standart output chanel
- move.l d0,OutHandle ;store it
- beq.s .Skip ;if not available then skip
- move.l OutHandle(pc),d1
- move.l #Hello.TXT,d2
- move.l #Hello.LEN,d3
- CALL DOS,Write ;print message
- .Skip
- ;===============================================
- SearchFlagOpt movea.l a5,a0 ;search for any flag options
- .SearchLoop move.b (a0)+,d0
- cmp.b #$0A,d0 ;jump out of loop if we
- beq.s Search ;find a return
- cmp.b #"?",d0 ;an request for info ?
- beq.s .PrintSyntax
- ori.b #$20,d0 ;make lower case (quick &dirty)
- cmp.b #"a",d0 ;ignore BIG-FAT-Agnus ?
- beq.s .OverRide
- cmp.b #"r",d0 ;non resident install ?
- bne.s .SearchLoop
-
- .Resident SF Flag_Resident+Flags ;clear Resident flag
- bra.s .SearchLoop
- .OverRide SF Flag_FatAgnus+Flags ;clear FAT agnus flag
- bra.s .SearchLoop
-
- .PrintSyntax move.l #Syntax.TXT,d2 ;Print syntax if we've found
- move.l #Syntax.LEN,d3 ;an '?'
- jmp PrintMsgAndQuit(pc)
-
- ;===============================================
- Search movea.l a5,a0 ;search for install options
- .SearchLoop move.b (a0),d0
- cmp.b #"i",d0
- beq.s InstallNTSC
- cmp.b #"I",d0
- beq.s InstallPAL
- ori.b #$20,d0 ;always lower case
- cmp.b #"k",d0
- beq.s Remove
- cmp.b #$0A,(a0)+
- bne.s .SearchLoop
-
- lea MyPortName(PC),a1 ;search emulator msg.port
- CALL EXEC,FindPort ;find my port
- tst.l d0
- beq.s InstallNTSC
-
- move.l #Already.TXT,d2
- move.l #Already.LEN,d3
- jmp PrintMsgAndQuit(pc)
-
- ;===============================================
- Remove BSR RemoveTag
- jmp PrintMsgAndQuit(pc)
-
- InstallNTSC sf Flag_60Hz+Flags ;install and start NTSC
- bra.s Install
- InstallPAL st Flag_60Hz+Flags ;install and Start PAL
-
- Install lea MyPortName(PC),a1 ;search emulator msg.port
- CALL EXEC,FindPort ;find my port
- tst.l d0
- beq.s .NotInstalled
-
- lea Message(pc),a1 ;send message to emulator
- move.l #'50'<<16,d2
- tst.b Flag_60Hz+Flags
- bne.s .pal
- move.l #'60'<<16,d2
-
- .pal move.b Flag_FatAgnus+Flags(pc),d2
- move.l d2,20(a1)
-
- move.l d0,a0 ;found port
- CALL EXEC,PutMsg
-
- .Waitting cmp.l Message.TXT(pc),d2 ;waiting for return msg
- beq.s .Waitting
-
- tst.l Message.TXT ;message = 0 ??
- bne.s .Error ;no -> something wrong
-
- move.l #Changed.TXT,d2
- move.l #Changed.LEN,d3
- bra.w PrintMsgAndQuit
-
- .Error move.l #UnChanged.TXT,d2
- move.l #UnChanged.LEN,d3
- bra.s PrintMsgAndQuit
-
- ;===============================================
- .NotInstalled BSR InstallTag ;install Tag
- bne.s PrintMsgAndQuit
-
- TagInstalled jsr 4(a0) ;Initialize emulator
- beq.s EmulatorOn
-
- BSR RemoveTag ;kill romtag if something wrong
-
- move.l #Failure.TXT,d2
- move.l #Failure.LEN,d3
- bra.s PrintMsgAndQuit
-
- EmulatorOn tst.b Flag_FatAgnus+Flags
- beq.s .Skip
-
- move.l #NewAgnus.TXT,d2
- move.l #NewAgnus.LEN,d3
- move.l OutHandle(pc),d1
- beq.s .Skip
- CALL DOS,Write ;print agnus message
-
- .Skip tst.b Flag_Resident+Flags
- bne.s .Skip2
-
- move.l #NResident.TXT,d2
- move.l #NResident.LEN,d3
- move.l OutHandle(pc),d1
- beq.s .Skip2
- CALL DOS,Write ;print resident message
-
- .Skip2 move.l #Installed.TXT,d2
- move.l #Installed.LEN,d3
-
- ;===============================================
- PrintMsgAndQuit BSR.S DoMessage
-
- CLOSELIB DOS ;close dos library
-
- NoDOS clr.l d0
- rts
-
- DoMessage move.l OutHandle(pc),d1
- beq.s .Skip
- CALL DOS,Write
-
- .Skip rts
-
- RemoveTag lea MyPortName(PC),a1 ;search emulator msg.port
- CALL EXEC,FindPort ;find my port
- tst.l d0
- bne.s FoundMyPort
-
- move.l #Unable.TXT,d2 ;can't find port !
- move.l #Unable.LEN,d3
- moveq #0,d0
- rts
-
- FoundMyPort move.l d0,a0 ;found port
- lea Message(pc),a1 ;send message to emulator
- move.l #'KILL',20(a1) ;kill MSG
- CALL EXEC,PutMsg ;to remove itself.
-
- Waitting cmp.l #'KILL',Message.TXT ;waiting for return msg
- beq.s Waitting
-
- tst.l Message.TXT ;message = 0 ??
- bne.s .Error ;no -> something wrong
-
- .Killed move.l #Removed.TXT,d2 ;all well, print remove
- move.l #Removed.LEN,d3 ;message
- moveq #-1,d0
- rts
-
- .Error move.l #Unable.TXT,d2 ;no -> something went
- move.l #Unable.LEN,d3 ;wrong
- moveq #-1,d0
- rts
-
-
- ;========================================================================
- Message DC.L 0 ;message to emulator
- DC.L 0
- DC.B NT_MESSAGE
- DC.B 0
- DC.L 0
- DC.L 0 ;reply port: geen
- DC.W Message.LEN
- Message.TXT DC.B "KILL"
- Message.LEN EQU *-Message.TXT
-
-
- DOSName DC.B "dos.library",$0
- EVEN
- DOSBase DC.L 0
- CodeMem DC.L 0
- OutHandle DC.L 0
-
- Hello.TXT DC.B $9B,"33;1m60Hz Emulator"
- DC.B $9B,"0m V1.05 by P. de Boer",$0A
- Hello.LEN EQU *-Hello.TXT
-
- Syntax.TXT DC.B "This program is shareware, NOT public domain !"
- DC.B $0A
- DC.B "Read the 60Hz.DOC file for more information !"
- DC.B $0A,$0A
- DC.B $9B,"1;33mSyntax....:"
- DC.B $9B,"0m 60Hz <OPTIONS>",$0A
- DC.B $9B,"1;33mOptions...:",$9B,"0m "
- DC.B "i = Install emulator and jump in NTSC mode.",$0A
- DC.B " "
- DC.B "I = Install emulator and jump in PAL mode.",$0A
- DC.B " "
- DC.B "K/k = Kill emulator !",$0A
- DC.B $9B,"1;33mAdditional:",$9B,"0m "
- DC.B "R/r = Install emulator NON-resident in memory",$0A
- DC.B " "
- DC.B "A/a = Ignore BIG FAT-Agnus, i.e. always software"
- DC.B " emulation",$0A,$0A
- DC.B "When the emulator is installed, ",$0A
- DC.B "press <LEFT-ALT>+<LEFT-SHIFT>+<CTRL> and ",$0A
- DC.B " ESC - To remove the emulator from memory",$0A
- DC.B " 0 - To toggle between PAL and NTSC",$0A
- DC.B " 9 - To toggle between Software and Hardware"
- DC.B " emulation",$0A
- DC.B " 1-8 - Reserved options (read 60Hz.DOC)",$0A
- DC.B $0A
- Syntax.LEN EQU *-Syntax.TXT
-
- NoMem.TXT DC.B "Not enough memory for emulator (I only need "
- DC.B "±2800 Bytes) !",$0A
- NoMem.LEN EQU *-NoMem.TXT
-
- Changed.TXT DC.B "60Hz Emulator flags updated !",$0A
- Changed.LEN EQU *-Changed.TXT
-
- UnChanged.TXT DC.B "Unable to update 60Hz Emulator flags !",$0A
- UnChanged.LEN EQU *-UnChanged.TXT
-
- Installed.TXT DC.B "60Hz Emulator installed !",$0A
- Installed.LEN EQU *-Installed.TXT
-
- Already.TXT DC.B "60Hz Emulator was already installed !",$0A
- Already.LEN EQU *-Already.TXT
-
- Removed.TXT DC.B "60Hz Emulator removed !",$0A
- Removed.LEN EQU *-Removed.TXT
-
- Unable.TXT DC.B "Unable to find Emulator in memory !",$0A
- Unable.LEN EQU *-Unable.TXT
-
- Failure.TXT DC.B "Installation failed !",$0A
- Failure.LEN EQU *-Failure.TXT
-
- NewAgnus.TXT DC.B "Fantastic, you got a BIG FAT-Agnus !!",$0A
- NewAgnus.LEN EQU *-NewAgnus.TXT
-
- NResident.TXT DC.B "Emulator will be gone after reset !",$0A
- NResident.LEN EQU *-NResident.TXT
-
- EVEN
-
- ;========================================================================
- InstallTag move.l #TagCodeLen,d0 ;allocate memory for
- moveq #MEMF_CHIP,d1 ;emulator
- CALL EXEC,AllocMem
- tst.l d0
- bne.s CopyTagCode
-
- move.l #NoMem.TXT,d2 ;not enough memory ??
- moveq #NoMem.LEN,d3
- moveq #-1,d0
- rts
-
- CopyTagCode movea.l d0,a5 ;a5 holds address of copy
- lea TagCode(PC),a0 ;copy code
- movea.l d0,a1
- move.l #TagCodeLen,d0
- CALL EXEC,CopyMem
-
- lea Flags(pc),a0
- tst.b Flag_Resident(a0)
- beq.s InitPort
-
- CALL EXEC,Forbid ;shut down system
- CALL EXEC,Disable
-
- lea RomTagPtrs-TagCode(a5),a0
- move.l KickTagPtr(a6),4(a0)
- beq.s NoTagYet
- bset #7,4(a0) ;set bit 31 if tag was set
-
- NoTagYet move.l a0,KickTagPtr(a6) ;install my romtag
- lea MyRomTag-TagCode(a5),a1
- move.l a1,(a0)
-
- InitMemList lea MyMemList-TagCode(a5),a1
- move.l a5,ML_SIZE+ME_ADDR(a1)
- move.l KickMemPtr(a6),d0
- move.l d0,LN_SUCC(a1)
- move.l a1,KickMemPtr(a6) ;install my memlist
-
- InitRomTag lea MyRomTag-TagCode(a5),a1
- move.l a1,RT_MATCHTAG(a1)
- lea RT_SIZE(a1),a2
- move.l a2,RT_ENDSKIP(a1)
- lea ProjectName-TagCode(a5),a2
- move.l a2,RT_NAME(a1)
- move.l a5,RT_INIT(a1)
- CALL EXEC,SumKickData
- move.l d0,KickCheckSum(a6) ;recalculate checksum
-
- InitPort lea MyPortName-TagCode(a5),a0
- lea MyPort-TagCode(a5),a1
- clr.l LN_SUCC(a1)
- clr.l LN_PRED(a1)
- move.l a0,LN_NAME(a1)
- CALL EXEC,AddPort ;add my port
-
- CALL EXEC,Enable ;powerup system
- CALL EXEC,Permit
-
- Exit movea.l a5,a0 ;pass code address
- clr.l d0
- rts
-
- ;========================================================================
- ;This piece of code will be resident in memory !
- ;========================================================================
-
- opt p+ ;code MUST be PC-relative !!!!
-
- TagCode JMP InitTagCode(pc) ;jump table
- JMP InitEmulator(pc)
-
- ;========================================================================
- InitTagCode movem.l d0-d7/a0-a6,-(SP) ;this routine
- ;will be executed
- lea MyPort(pc),a1 ;in the reset routine
- lea MyPortName(PC),a0
- clr.l LN_SUCC(a1)
- clr.l LN_PRED(a1)
- move.l a0,LN_NAME(a1)
- CALL EXEC,AddPort
-
- BSR.S InitEmulator ;re-init emulator
-
- EndTagCode movem.l (SP)+,d0-d7/a0-a6 ;return to kicky
- rts
-
- ;========================================================================
- InitEmulator BSR.S InitStructures
-
- lea Flags(pc),a0
- sf Flag_Enable(a0) ;prevent interrupt
- BSR.S OpenIntLib ;open int library (for alerts)
- BSR.S OpenResource ;open ciab.resource (for timer)
- BNE.S .Failure
- BSR PatchSystem ;patch system to pal/ntsc
- BNE.S .Failure
- BSR AddServers ;add ciaa & vblank servers
-
- clr.l d0
- .Failure rts
-
- ;========================================================================
- Alert clr.l d0 ;display alert
- moveq #32,d1
- movea.l INTBase(pc),a6
- jsr _LVODisplayAlert(a6)
- rts
- ;===============================================
- OpenIntLib lea INTName(pc),a1
- clr.l d0
- CALL EXEC,OpenLibrary
- lea INTBase(pc),a0
- move.l d0,(a0)
- bne.s .Skip
- rts
- move.l #$04030000,d7 ;software failure
- lea $FC00D2,a5 ;if intuition.library
- CALL EXEC,Alert ;didn't open
- .Skip rts
- ;===============================================
- InitStructures lea TagCode(pc),a0 ;relocate structures !
- move.l a0,d0
- lea CIAA_Server(pc),a0
- BSR.S .InitStruct
- lea CIAB_Server(pc),a0
- BSR.S .InitStruct
- lea VBI_Server(pc),a0
- .InitStruct add.l d0,LN_NAME(a0)
- add.l d0,is_data(a0)
- add.l d0,is_code(a0)
- lea InitStructures(pc),a0
- move.w #$4E75,(a0) ;put RTS at InitStruct
- rts
- ;===============================================
- OpenResource lea CIABName(pc),a1 ;open ciab.resource
- clr.l d0
- CALL EXEC,OpenResource
- lea CIABBase(pc),a0
- move.l d0,(a0)
- beq.s .Error
- moveq #0,d0
- rts
- .Error lea NoResourceAlert(pc),a0 ;no resource ??
- BSR Alert
- moveq #-1,d0
- rts
-
- ;===============================================
- AllocateTimer move.b #0,d0 ;timer a interrupt
- lea CIAB_Server(pc),a1
- move.l CIABBase(pc),a6
- jsr -6(a6) ;set interrupt
- lea TimerStat(pc),a0
- move.l d0,(a0) ;store timer status
- beq.s .Ok
-
- .Error lea NoTimerAlert(pc),a0 ;no timer !
- BSR Alert
- moveq #-1,d0
- .Ok rts
-
- ;===============================================
- DeAllocateTimer lea TimerStat(pc),a0
- tst.l (a0)
- bne.s .Skip
- move.b #0,d0
- move.l CIABBase(pc),a6
- jsr -12(a6) ;clr interrupt
-
- lea TimerStat(pc),a0
- moveq #-1,d0
- move.l d0,(a0)
-
- .Skip rts
-
- ;===============================================
- AddServers lea Flags(pc),a0
- sf Flag_Enable(a0)
-
- move.w #$0005,d0 ;vertical blank interrupt
- lea VBI_Server(pc),a1
- CALL EXEC,AddIntServer
- move.w #$0003,d0 ;keyboard interrupt
- lea CIAA_Server(pc),a1
- CALL EXEC,AddIntServer
-
- lea Flags(pc),a0
- st Flag_Enable(a0)
-
- rts
- ;===============================================
- PatchSystem lea Flags(pc),a0 ;this routine does it !
- tst.b Flag_60Hz(a0)
- beq.s Go60
-
- ;===============================================
- Go50 tst.b Flag_FatAgnus(a0) ;put system in PAL mode
- bne.s .Go50
- BSR.S DeAllocateTimer ;free timers
-
- .Go50 move.w #$0020,BEAMCON0!CUSTOM ;very simple if we have a FAT
-
- lea Flags(pc),a0
- sf Flag_Enable(a0) ;stop it
-
- lea GFXName(PC),a1
- clr.l d0
- CALL EXEC,OpenLibrary ;open graphics library
- move.l d0,a1
- move.w gb_DisplayFlags(a1),d0 ;adjust display flags
- and.b #%11111110,d0 ;erase NTSC flag
- or.b #%00000100,d0 ;set PAL flag
- move.w d0,gb_DisplayFlags(a1)
- move.w #256,gb_NormalDisplayRows(a1)
- move.w #311,gb_DisplayRows(a1)
- or.b #LIBF_CHANGED,LIB_FLAGS(a1)
- movea.l a1,a2
- CALL EXEC,SumLibrary ;caluclate checksum
- movea.l a2,a1
- CALL EXEC,CloseLibrary ;close lib again
- move.b #50,VBlankFrequency(a6) ;change EXEC library
- or.b #LIBF_CHANGED,LIB_FLAGS(a6)
- CALL EXEC,SumLibrary ;calculate checksum
- moveq #0,d0
- rts
-
- ;===============================================
- Go60 tst.b Flag_FatAgnus(a0) ;put system in NTSC mode
- beq.s .NoFatty
-
- move.w #$0000,BEAMCON0!CUSTOM ;to NTSC please
- bra.s .Go60
-
- .NoFatty move.w #$0020,BEAMCON0!CUSTOM
- BSR AllocateTimer ;allocate timers again
- bne.s .Error ;not available
-
- .Go60 lea GFXName(PC),a1 ;modify graphics.library
- clr.l d0
- CALL EXEC,OpenLibrary
- move.l d0,a1
- move.w gb_DisplayFlags(a1),d0
- and.b #%11111011,d0
- or.b #%00000001,d0
- move.w d0,gb_DisplayFlags(a1)
- move.w #200,gb_NormalDisplayRows(a1)
- move.w #262,gb_DisplayRows(a1)
- or.b #LIBF_CHANGED,LIB_FLAGS(a1)
- movea.l a1,a2
- CALL EXEC,SumLibrary
- movea.l a2,a1
- CALL EXEC,CloseLibrary
- move.b #60,VBlankFrequency(a6)
- or.b #LIBF_CHANGED,LIB_FLAGS(a6)
- CALL EXEC,SumLibrary
-
- lea Flags(pc),a0
- st Flag_Enable(a0) ;start it
- moveq #0,d0
- rts
-
- .Error lea Flags(pc),a0
- st Flag_60Hz(a0)
- sf Flag_Enable(a0) ;stop it
- moveq #-1,d0
- rts
-
- ;========================================================================
- CIAA_Server_Int movem.l d0-d7/a0-a6,-(SP) ;keyboard interrupt
-
- st d1 ;server
- lea EnterKeys(pc),a0
- move.b CIAA!SPx,d5
- not.b d5
- ror.b #1,d5
- bmi.s .NotPressed
- sf d1
- .NotPressed andi.b #$7F,d5
- .TestCTRL cmp.b #$63,d5
- bne.s .TestSHIFT
- move.b d1,(a0)
- .TestSHIFT cmp.b #$60,d5
- bne.s .TestALT
- move.b d1,1(a0)
- .TestALT cmp.b #$64,d5
- bne.s .EndTest
- move.b d1,2(a0)
- .EndTest tst.b d1
- bne.s CIAA_Return
-
- AreWeInControl tst.l (a0)
- bne.s CIAA_Return
- cmp.b #$45,d5
- beq.s .Go
- cmp.b #$0A,d5
- bgt.s CIAA_Return
-
- .Go ori.b #$40,CIAA!CRA
- nop
- nop
- andi.b #$BF,CIAA!CRA
- nop
- nop
- clr.b CIAA!SPx
-
- lea Flags(pc),a5
- BSR CheckESC
- tst.b Flag_Enable(a5)
- beq.s .Skip
- tst.b Flag_FatAgnus(a5)
- bne.s .Skip
- BSR CheckColor ;check keys
- BSR CheckTime
- BSR CheckStartPos
- BSR CheckEndPos
- BSR CheckDefault
- .Skip BSR Check60Hz
- BSR CheckAgnus
- CIAA_Return movem.l (SP)+,d0-d7/a0-a6
- DC.W $003C,$0004
- rts
-
- ;========================================================================
- VBI_Server_Int movem.l d0-d7/a0-a6,-(SP) ;vertical blank interrupt
-
- lea Flags(pc),a0 ;server
- tst.b Flag_Enable(a0) ;are we in 60Hz mode ?
- beq.s .Skip ;if not then skip
-
- lea CUSTOM,a0 ;custom chip base
- move.w DMACONR(a0),d1 ;read DMACON
- move.w #$0440,DMACON(a0) ;clear blitpri & blitdma
-
- clr.w d0
- move.b VHPOSR(a0),d0 ;read actual beam pos
- neg.w d0 ;make it negative
- add.w EndPos(pc),d0 ;add endpos
- mulu #45,d0 ;multiply with cycle/line
- sub.w VBITime(pc),d0 ;subtrack buffer time
- move.b d0,$bfd400 ; Timer A high byte
- lsr.w #8,d0 ;get low byte
- move.b d0,$bfd500 ; Timer A low byte
- move.b #%00011001,$BFDE00 ;load timer-a
-
- andi.w #$0440,d1 ;reinstall dma again
- ori.w #$8000,d1
- move.w d1,DMACON(a0) ;write it in dmacon
-
- .Skip BSR.S CheckForMSG ;check for incoming msg
-
- movem.l (SP)+,d0-d7/a0-a6
- DC.W $003C,$0004 ;or.w #$4,SR ;set Z-Flag
- rts
-
- ;========================================================================
- CIAB_Server_Int movem.l d0-d2/a0,-(a7)
- lea Flags(pc),a0
- tst.b Flag_Enable(a0)
- beq.s GetOutOfHere
- lea CUSTOM,a0 ;get custom base address
- move.w DMACONR(a0),d2 ;read dma
- move.w #$0440,DMACON(a0) ;clear blitpri&blitdma
- move.w EndPos(pc),d1
- lsl.w #8,d1
- ori.w #$D1,d1
- StartColor move.w #$0505,$1FE(a0) ;put colorbar if needed
- move.w EndPos(pc),d0 ;wait for line 'EndPos'
- WaitLine cmp.b VHPOSR(a0),d0
- bgt.s WaitLine
- move.w d1,DIWSTOP(a0)
- EndColor move.w #$0000,$1FE(a0)
- move.l StartPos(pc),d1
- move.l VPOSR(a0),d0 ;prevents shocking
- sub.l VPOSR(a0),d0 ;of menu bar
- sub.l d0,d1 ;subtract it from StartPos
- add.l VPOSR(a0),d1 ;add current beam pos
- move.l d1,VPOSW(a0) ;write new beampos
- andi.w #$0440,d2 ;
- ori.w #$8000,d2
- move.w d2,DMACON(a0) ;enable blitpri&blitdma
- GetOutOfHere movem.l (a7)+,d0-d2/a0 ;return to system
- rts
-
- ;========================================================================
- CheckForMSG lea MyPort(pc),a0 ;check message port
- CALL EXEC,GetMsg ;get message
- tst.l d0
- beq.s .NoMSG ;mmmm.. no message
-
- move.l d0,a5 ;got message, yeah !
- cmp.l #"KILL",20(a5) ;is it a 'KILL' message ??
- beq.s MSG.Kill
-
- move.l 20(a5),d2
-
- lea Flags(pc),a4
- cmp.b Flag_FatAgnus(a4),d2 ;change in emulation mode ?
- beq.s .Skip ;no then skip
-
- tst.b Flag_FatAgnus(a4)
- beq.s .DeAllocTimer
- BSR AllocateTimer
- bne.s .Skip
-
- .DeAllocTimer BSR DeAllocateTimer
- not.b Flag_FatAgnus(a4)
-
- .Skip swap d2
- cmp.w #"50",d2
- beq.s MSG.50Hz
- cmp.w #"60",d2
- beq.s MSG.60Hz
-
- .Exit move.l d0,20(a5)
-
- .NoMSG rts
-
- MSG.50Hz lea Flags(pc),a0 ;recieved 50Hz message
- tst.b Flag_60Hz(a0)
- bne.s .Already50Hz
- st Flag_60Hz(a0)
- BSR PatchSystem
- .Already50Hz clr.l 20(a5)
- rts
-
- MSG.60Hz lea Flags(pc),a0 ;recieved 60Hz message
- tst.b Flag_60Hz(a0)
- beq.s .Already60Hz
- sf Flag_60Hz(a0)
- BSR PatchSystem
- move.l d0,20(a5)
- rts
- .Already60Hz clr.l 20(a5)
- rts
-
- MSG.Kill BSR KillEmulator ;yes? -> kill me (?)
- move.l d0,20(a5)
- rts
-
- ;========================================================================
- ;Subroutines for key checking !
- ;
- ;=======================================
- CheckColor cmp.b #$01,d5
- bne.s .NoColorFlag
- lea EndColor+4(pc),a1 ;self-modifying code
- lea StartColor+4(pc),a2 ;not so nice, but it works
- not.b Flag_Color(a5)
- beq.s .ColorOff
- .ColorOn move.w #COLOR00,(a1) ;
- move.w #COLOR00,(a2)
- bra.s .NoColorFlag
- .ColorOff move.w #$01FE,(a1) ;copper instruction $1FE
- move.w #$01FE,(a2) ;is NO-OP (no operation)
- .NoColorFlag rts
- ;=======================================
- CheckAgnus cmp.b #$09,d5
- bne.s .NoAgnusCheck
-
- move.w $DFF004,d0 ;check what kind of agnus
- and.w #$2000,d0 ;we got
- beq.s .NoAgnusCheck ;no big agnus ? how lame !
-
- tst.b Flag_FatAgnus(a5)
- beq.s .DeAllocTimer
- BSR AllocateTimer
- bne.s .NoAgnusCheck
-
- .DeAllocTimer BSR DeAllocateTimer
- not.b Flag_FatAgnus(a5)
-
- .Skip BSR PatchSystem
-
- .NoAgnusCheck rts
- ;=======================================
- CheckTime lea VBITime(pc),a1
- cmp.b #$03,d5
- beq.s .NoAdd
- sub.w #45,(a1)
- .NoAdd cmp.b #$04,d5
- beq.s .NoSub
- add.w #45,(a1)
- .NoSub rts
- ;=======================================
- CheckStartPos lea StartPos(pc),a1
- cmp.b #$05,d5
- beq.s .NoAdd
- add.l #$0100,(a1)
- .NoAdd cmp.b #$06,d5
- beq.s .NoSub
- sub.l #$0100,(a1)
- .NoSub rts
- ;=======================================
- CheckEndPos lea EndPos(pc),a1
- cmp.b #$07,d5
- beq.s .NoAdd
- addq.w #$0001,(a1)
- .NoAdd cmp.b #$08,d5
- beq.s .NoSub
- subq.w #$0001,(a1)
- .NoSub rts
- ;=======================================
- CheckDefault cmp.b #$02,d5
- bne.s .Skip
- lea EndPos(pc),a1
- move.w #$0104,(a1)
- lea StartPos(pc),a1
- move.l #$3203,(a1)
- lea VBITime(pc),a1
- move.w #8*45,(a1)
- .Skip rts
- ;=======================================
- Check60Hz cmp.b #$0A,d5
- bne.s .Skip
- not.b Flag_60Hz(a5)
- BSR PatchSystem
- .Skip rts
- ;=======================================
- CheckESC cmp.b #$45,d5
- bne.s .Skip
- BSR.S KillEmulator
- .Skip rts
- ;========================================================================
- KillEmulator CALL EXEC,Disable
- move.w #$0005,d0 ;vertical blank interrupt
- lea VBI_Server(pc),a1
- CALL EXEC,RemIntServer
- move.w #$0003,d0 ;keyboard interrupt
- lea CIAA_Server(pc),a1
- CALL EXEC,RemIntServer
- lea Flags(pc),a0
- st Flag_60Hz(a0)
- BSR PatchSystem
- BSR.S RemoveRomTag
- move.l d0,d2
- CALL EXEC,Enable
- rts
- ;========================================================================
- RemoveRomTag lea MyPortName(PC),a1
- CALL EXEC,FindPort ;find my port
- tst.l d0
- bne.s FoundPort
- moveq #-1,d0 ;no port found ??
- rts
-
- FoundPort move.l d0,a4 ;a4 = pointer to MyPort
- move.l a4,a1
- CALL EXEC,RemPort ;remove it !
-
- lea Flags(pc),a0
- tst.b Flag_Resident(a0)
- beq.s FreeMemory
-
- CALL EXEC,Forbid ;shut down system
- CALL EXEC,Disable
-
- lea MyMemList-MyPort(a4),a1 ;find my memlist
- lea KickMemPtr(a6),a0
- FindMyMemList move.l LN_SUCC(a0),d0
- cmp.l d0,a1
- beq.s FoundMyList
- move.l d0,a0
- bra.s FindMyMemList
-
- FoundMyList move.l LN_SUCC(a1),d0 ;clear memlist from system
- move.l d0,LN_SUCC(a0) ; LN_SUCC = 0, so this also
- ; works for KickMemPtr
-
- move.l RomTagPtrs-MyPort+4(a4),KickTagPtr(a6)
- beq.s NoSecondTag
- bclr #7,KickTagPtr(a6) ;clear bit 31
-
- NoSecondTag CALL EXEC,SumKickData
-
- tst.l KickTagPtr(a6) ;check if one of the
- bne.s .Set ;ptrs is set
- tst.l KickMemPtr(a6) ;if so, then no need
- bne.s .Set ;to calc checksum
- clr.l d0 ;so, clear it !
-
- .Set move.l d0,KickCheckSum(a6) ;restore old
-
- CALL EXEC,Enable ;power up system
- CALL EXEC,Permit
-
- FreeMemory lea TagCode-MyPort(a4),a1 ;free tag memory
- move.l #TagCodeLen,d0
- CALL EXEC,FreeMem
-
- clr.l d0
- rts
-
- ;========================================================================
- CIAA_Server DC.L 0 ;interrupt server structure
- DC.L 0
- DC.B 2 ;type = interrupt
- DC.B 127 ;pri
- DC.L ProjectName-TagCode
- DC.L CIAA_Server-TagCode
- DC.L CIAA_Server_Int-TagCode
-
- CIAB_Server DC.L 0
- DC.L 0
- DC.B 2 ;type = interrupt
- DC.B 127 ;pri
- DC.L ProjectName-TagCode
- DC.L CIAB_Server-TagCode
- DC.L CIAB_Server_Int-TagCode
-
- VBI_Server DC.L 0
- DC.L 0
- DC.B 2 ;type = interrupt
- DC.B 127 ;pri
- DC.L ProjectName-TagCode
- DC.L VBI_Server-TagCode
- DC.L VBI_Server_Int-TagCode
-
- MyMemList DS.B LN_SIZE ;memlist structure
- DC.W 1
- DC.L NULL
- DC.L TagCodeLen
-
- MyPort DC.L NULL ;message port structure
- DC.L NULL
- DC.B NT_MSGPORT
- DC.B 0
- DC.L NULL
- DC.B 0
- DC.B 0
- DC.L NULL
- DS.B 14
-
- MyRomTag DC.W RTC_MATCHWORD ;resident structure
- DC.L NULL
- DC.L NULL
- DC.B RTF_COLDSTART
- DC.B 1
- DC.B 0
- DC.B -10
- DC.L NULL
- DC.L NULL
- DC.L 0
-
- ;========================================================================
- ProjectName DC.B "60Hz emulator V1.05 by P. de Boer",$0
- MyPortName DC.B "60Hz emulator V1.05 (port)",$0
- EVEN
-
- CIABName DC.B "ciab.resource",$0
- INTName DC.B "intuition.library",$0
- GFXName DC.B "graphics.library",$0
- EVEN
-
- NoTimerAlert DC.W 20
- DC.B 17
- DC.B "Emulator failure: "
- DC.B "CIA-B Timer-A already in use !",$0
- EVEN
-
- NoResourceAlert DC.W 20
- DC.B 17
- DC.B "Emulator failure: "
- DC.B "Unable to open ciab.resource !",$0
- EVEN
-
- StartPos DC.L $3202 ;Start pos
- EndPos DC.W $0104
-
- Flags DCB.B 8
- EnterKeys DC.L $FFFFFF00
- VBITime DC.W 8*45 ;buffer time (important !)
-
- TimerStat DC.L -1
- INTBase DC.L 0
- CIABBase DC.L 0
- RomTagPtrs DCB.L 2,$0
-
- TagCodeLen EQU *-TagCode
-
- ;========================================================================
- ;|
-